/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package ace.game.entity.bullet;

import ace.game.GradientLine;
import ace.game.Sprite;
import ace.game.entity.enemy.Enemy;
import ace.game.entity.Entity;
import ace.game.entity.LivingEntity;
import ace.geometry.Vector2D;
import ace.geometry.Vertex2D;
import ace.system.StateManager;
import javax.microedition.lcdui.Graphics;
import ace.system.Utilities;

/**
 *
 * @author LegACy
 */
public class Bullet extends Entity {
	protected Bullet() {
		//Initialize
		position	= new Vertex2D();
		mDirection	= new Vector2D();
		mTimer		= 0;
		mData		= null;
		mTarget		= null;
		mActive		= true;
		mExploding	= false;
	}

	public Bullet(BulletData data, Vertex2D inPos, Vector2D direction) {
		//Default
		this(data, inPos);

		mDirection = direction;
        mMaximumVelocity = mDirection.x * mDirection.x + mDirection.y * mDirection.y;
        mMaximumVelocity = (float)Math.sqrt(mMaximumVelocity) * 10;
	}

	public Bullet(BulletData data, Vertex2D inPos, LivingEntity target) {
		//Default
		this(data, inPos);

		mTarget		= target;
	}

    // bullet which move a bit before seeking the enemy
    public Bullet(BulletData data, Vertex2D inPos, Vector2D direction, LivingEntity target, long seekingDelay) {
		//Default
		this(data, inPos, direction);

		mTarget         = target;
        mSeekingDelay   = seekingDelay;
	}

    private Bullet(BulletData data, Vertex2D inPos) {
        this();
        position	= inPos;
		mData		= data;
    }

	public LivingEntity getTarget()	{	return mTarget;		}
	public boolean isActive()       {	return mActive;		}
	public BulletData getData()     {	return mData;		}
	public boolean isExploding()    {	return mExploding;	}
    public Vector2D getDirection()  {   return mDirection;  }

    public void explode() {
        mExploding  = true;
        mActive     = false;
    }

	public void update(long time) {
		mTimer += time;
		if (mTimer >= mData.getDuration()) mActive = false;
		if (mTarget != null && mTimer > mSeekingDelay) {
			// seeking type bullet

			//Skip if no enemy
			if (mTarget.getHealth() <= 0) mActive = false;

			//set new velocity
            final float dist = Vertex2D.range(mTarget.position, position);
            mDirection.x = (position.x - mTarget.position.x) / dist * mMaximumVelocity;
            mDirection.y = (position.y - mTarget.position.y) / dist * mMaximumVelocity;
		}

		if (mActive) {
			position.x -= time * mDirection.x;
			position.y -= time * mDirection.y;
		}
        // update sprite
        Sprite sprite = mData.getSprite();
        if (sprite != null) {
            sprite.update(time);
        }
	}

	public void draw(Graphics g, int startX, int startY, int endX, int endY) {
		if (!mActive) return;

		//Draw
		Sprite sprite = mData.getSprite();
		GradientLine gradient = mData.getGradient();

        //Get rect
		int Left	= (int)(position.x - startX );
		int Top		= (int)(position.y - startY );

        boolean shouldDraw = true;

		//Ensure in drawing area
		if (Left < 0)                                       shouldDraw = false;
		else if(Left > StateManager.instance().getWidth())	shouldDraw = false;
		else if (Top < 0)                                   shouldDraw = false;
		else if (Top > StateManager.instance().getHeight())	shouldDraw = false;

        if (!shouldDraw) {
            //mActive = false;
            return;
        }

		if (sprite != null) {
			// use sprite to draw
			sprite.setPosition((int)(position.x - startX), (int)(position.y - startY));
			sprite.draw(g, Graphics.HCENTER | Graphics.VCENTER);
		} else if (gradient != null) {
			// use particle to draw (gradient for now)

			gradient.x1 = (int)(position.x - startX);
			gradient.y1 = (int)(position.y - startY);
			gradient.x2 = (int)(position.x + mDirection.x * 15 - startX);
			gradient.y2 = (int)(position.y + mDirection.y * 15 - startY);


			gradient.x1 -= 2;
			gradient.x2 -= 2;
			for (int i = -1; i < 1; ++i) {
				++gradient.x1;
				++gradient.x2;
				gradient.draw(g);
			}
		}
	}

	protected long			mTimer;
	protected BulletData	mData;
	protected boolean		mActive;
	protected LivingEntity  mTarget;
	protected boolean		mExploding;
    protected long          mSeekingDelay;
    protected float         mMaximumVelocity;

	private Vector2D mDirection;
}
